﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Management.Automation;
using System.Management.Automation.Host;
using System.Management.Automation.Runspaces;

namespace ex2l10_test1
{
    public partial class Form1 : Form
    {
        Splash sp;

        public Form1()
        {
            InitializeComponent();
        }
        //DECLARE IF LOGGING IS ENABLED OR NOT
        bool loggingEnabled = false;
        string selectedRole ="";
        string selectedRoleEntry = "";
        string selectedRoleEntryParameter = "";
        string selectedMgmtRoleType = "";
        string selectedRolesParentRole;
        string selectedAssignment;
        bool showRoleEntriesWorking;
        bool showRoleEntryParametersWorking;
        int selectedRoleIndex;

        private bool checkIfExchangeSnappinExists()
        {
            RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();
            PSSnapInException snapInException = null;

            try
            {
                PSSnapInInfo info = rsConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out snapInException);
            }
            catch (PSArgumentException)
            {
                return false;
            }
            catch (Exception)
            {
                return false;
            }

            return true;
        }

        void DoSplash()
        {
            sp = new Splash();
            sp.ShowDialog();
        }

      

        public Collection<PSObject> resultOfCmdlet(string script)
        {
            try
            {
                RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();
                PSSnapInException snapInException = null;
                PSSnapInInfo info = rsConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out snapInException);
                Runspace myRunSpace = RunspaceFactory.CreateRunspace(rsConfig);
                myRunSpace.Open();

                Pipeline pipeLine = myRunSpace.CreatePipeline();

                Command myCommand = new Command(script, true);

                pipeLine.Commands.Add(myCommand);

                Collection<PSObject> commandResults = pipeLine.Invoke();

                if (loggingEnabled == true)
                {
                    string pathLogging = Environment.GetEnvironmentVariable("temp") + "\\RBAC.txt";
                    System.IO.StreamWriter sw = new System.IO.StreamWriter(pathLogging, true);
                    sw.WriteLine(DateTime.Now.ToString());
                    sw.WriteLine("===================");
                    sw.WriteLine(script);
                    sw.WriteLine();
                    sw.Close();
                }

                return commandResults;
            }
            catch (Exception Ex)
            {
                MessageBox.Show(Ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return null;
            }
        } // end of resultOfCmdlets

        private void Form1_Load(object sender, EventArgs e)
        {
            Thread th = new Thread(DoSplash);

            th.Start();



            if (checkIfExchangeSnappinExists())
            {
                populateCmdletFilters();
                showRoles("none", "none");
            }
            else
            {
                MessageBox.Show("Exchange Server 2010 Management Tools is not installed", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Application.Exit();
            }


            sp.Close();

            try
            {
                th.Abort();
            }
            catch { }
            
            this.Activate();
            
        }
        private void showAssingments()
        {
            treeAssignments.Nodes.Clear();

            treeAssignments.Nodes.Add("ROLE ASSIGNMENTS");

            string getManagementRoleAssignmentCmdlet = "Get-ManagementRoleAssignment -Role \"" + selectedRole + "\"";
            Collection<PSObject> getManagementRoleAssignmentResults = resultOfCmdlet(getManagementRoleAssignmentCmdlet);

            int nodeNumber = 1;
            int nodeNumber2 = 0;

            foreach(PSObject assignment in getManagementRoleAssignmentResults)
            {
                
                treeAssignments.Nodes.Add(assignment.Properties["Name"].Value.ToString());
                treeAssignments.Nodes[nodeNumber].Tag = "Assignment";
                treeAssignments.Nodes[nodeNumber].ForeColor = System.Drawing.Color.Green;
                
                treeAssignments.Nodes[nodeNumber].Nodes.Add(assignment.Properties["RoleAssigneeName"].Value.ToString());
                treeAssignments.Nodes[nodeNumber].Nodes[nodeNumber2].Tag = "Assignee";

                nodeNumber++;
            }
        }

        private void showRoles(string cmdletFilter,string cmdletParametersFilter)
        {
            treeRoles.Nodes.Clear();
            string getManagementRoleCmdlet;

            treeRoles.Nodes.Add("MANAGEMENT ROLES");
            if(cmdletFilter == "none" & cmdletParametersFilter == "none")
                getManagementRoleCmdlet = "Get-ManagementRole | Sort-Object";
            else if (cmdletFilter != "none" & cmdletParametersFilter == "none")
                getManagementRoleCmdlet = "Get-ManagementRole -Cmdlet " + cmdletFiltertextBox.Text + " | Sort-Object"; 
            else if (cmdletFilter == "none" & cmdletParametersFilter != "none")
                getManagementRoleCmdlet = "Get-ManagementRole -CmdletParameters " + cmdletParametersFiltertextBox.Text + " | Sort-Object"; 
            else
                getManagementRoleCmdlet = "Get-ManagementRole -Cmdlet " + cmdletFiltertextBox.Text + " -CmdletParameters " + cmdletParametersFiltertextBox.Text + " | Sort-Object";


            Collection<PSObject> getManagementRoleResults = resultOfCmdlet(getManagementRoleCmdlet);

            int nodeNumber = 1;
            

            foreach(PSObject role in getManagementRoleResults)
            {
                int nodeNumber2 = 0;
                if (role.Properties["IsRootRole"].Value.ToString() == "True")
                {
                    treeRoles.Nodes.Add(role.Properties["Name"].Value.ToString());
                    treeRoles.Nodes[nodeNumber].Tag = "Role";
                    treeRoles.Nodes[nodeNumber].ForeColor = System.Drawing.Color.Green;

                    string currentRoleType = role.Properties["RoleType"].Value.ToString();

                    foreach (PSObject role2 in getManagementRoleResults)
                    {
                        if (role2.Properties["IsRootRole"].Value.ToString() == "False" && role2.Properties["RoleType"].Value.ToString() == currentRoleType)
                        {
                            treeRoles.Nodes[nodeNumber].Nodes.Add(role2.Properties["Name"].Value.ToString());
                            treeRoles.Nodes[nodeNumber].Nodes[nodeNumber2].Tag = "CustomRole";
                            treeRoles.Nodes[nodeNumber].Nodes[nodeNumber2].ForeColor = System.Drawing.Color.Blue;
                            nodeNumber2++;
                        }
                    }
                    nodeNumber++;
                }
            }

           

        }// end of showRoles()

      
        private void buttonFilter_Click(object sender, EventArgs e)
        {
            showRoles(cmdletFiltertextBox.Text,cmdletParametersFiltertextBox.Text);
        }
        
        //CATCHS MOUSE LEFT\RIGHT CLICK ACTIONS FOR FIRST PANE
        private void treeRoles_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                Point p = new Point(e.X, e.Y);
                TreeNode node = treeRoles.GetNodeAt(p);

                if (node != null)
                {
                    //m_OldSelectNode2 = connectorsTree.SelectedNode;
                    treeRoles.SelectedNode = node;
                    selectedRole = treeRoles.SelectedNode.ToString().Replace("TreeNode:", "").Trim();
                    selectedRoleIndex = treeRoles.SelectedNode.Index;
                    selectedMgmtRoleType = treeRoles.SelectedNode.Tag.ToString();

                    showAssingments();
                    showRoleEntries();

                    switch (Convert.ToString(node.Tag))
                    {
                        case "Server?": //RESERVED FOR FUTURE RELEASES
                            //connectorContextMenu.Show (treeReceiveConnector, p);
                            break;
                        case "Role":
                            RolesContextMenu.Show(treeRoles, p);
                            break;
                        case "CustomRole":
                            customRolesContextMenu.Show(treeRoles, p);
                            break;
                    }
                }
            }
            if (e.Button == MouseButtons.Left)
            {
                try { checkedListBoxRoleEntries.SelectedIndex = 0; }
                catch { }
                //treePermissions.Nodes.Clear();
                Point p = new Point(e.X, e.Y);
                TreeNode node = treeRoles.GetNodeAt(p);
                if (node.Level != 0)
                {
                    //lParentNode.Text = node.Parent.Text;
                    selectedRolesParentRole = node.Parent.Text;
                }
            
                treeRoles.SelectedNode = node;
                selectedMgmtRoleType = treeRoles.SelectedNode.Tag.ToString();
                //labelSelectedMgmtRole.Text = treeRoles.SelectedNode.Tag.ToString();
                selectedRole = treeRoles.SelectedNode.ToString().Replace("TreeNode:", "").Trim();
                //labelSelectedMgmtRole.Text = selectedRole;
                
                showAssingments();
                showRoleEntries();

            }
        } // end of Mouse_Up

        //SHOW ROLES
        private void showRoleEntries()
        {
            showRoleEntriesWorking = true;
           
            checkedListBoxRoleEntries.Items.Clear();
            checkedListBoxRoleEntryParams.Items.Clear();
            ArrayList customRoleEntriesList = new ArrayList();
            string getManagementRolePipeRoleEntries ="";
            string getManagementCustomRolePipeRoleEntries ="";
            int listBoxIndex = 1;
            if (selectedMgmtRoleType == "Role")
                getManagementRolePipeRoleEntries = "Get-ManagementRole \"" + selectedRole + "\" | %{$_.RoleEntries} | Sort-Object";
            else
            {
                getManagementRolePipeRoleEntries = "Get-ManagementRole \"" + selectedRolesParentRole + "\" | %{$_.RoleEntries} | Sort-Object";
                getManagementCustomRolePipeRoleEntries = "Get-ManagementRole \"" + selectedRole + "\" | %{$_.RoleEntries} | Sort-Object";

                Collection<PSObject> getManagementRolePipeCustomRoleEntriesResults = resultOfCmdlet(getManagementCustomRolePipeRoleEntries);
                foreach (PSObject customRoleEntry in getManagementRolePipeCustomRoleEntriesResults)
                {
                    customRoleEntriesList.Add(customRoleEntry.Properties["Name"].Value.ToString());
                }
            }

            Collection<PSObject> getManagementRolePipeRoleEntriesResults = resultOfCmdlet(getManagementRolePipeRoleEntries);
            checkedListBoxRoleEntries.Items.Add("ROLE ENTRIES");
            checkedListBoxRoleEntries.SetItemCheckState(0, CheckState.Indeterminate);
            foreach (PSObject roleEntry in getManagementRolePipeRoleEntriesResults)
            {
                checkedListBoxRoleEntries.Items.Add(roleEntry.Properties["Name"].Value.ToString());
                
                if(selectedMgmtRoleType == "Role")
                    checkedListBoxRoleEntries.SetItemCheckState(listBoxIndex, CheckState.Indeterminate);
                else if(customRoleEntriesList.Contains(roleEntry.Properties["Name"].Value.ToString()))
                    checkedListBoxRoleEntries.SetItemCheckState(listBoxIndex, CheckState.Checked);
                else
                    checkedListBoxRoleEntries.SetItemCheckState(listBoxIndex, CheckState.Unchecked);

                listBoxIndex++;
          }
            showRoleEntriesWorking = false;
        }
        //SHOW PARAMETERS
        private void showRoleEntryParameters()
        {
            showRoleEntryParametersWorking = true;
            checkedListBoxRoleEntryParams.Items.Clear();

            int listBoxIndex = 0;
            ArrayList customRoleEntryParametersList = new ArrayList();
            string getManagementRolePipeRoleEntryParams = "";
            if (selectedMgmtRoleType == "Role")
                getManagementRolePipeRoleEntryParams = "Get-ManagementRole \"" + selectedRole + "\" | %{$_.RoleEntries} | ?{$_.name -eq \"" + selectedRoleEntry + "\"} | %{$_.parameters}";
            else
            {
                getManagementRolePipeRoleEntryParams = "Get-ManagementRole \"" + selectedRolesParentRole + "\" | %{$_.RoleEntries} | ?{$_.name -eq \"" + selectedRoleEntry + "\"} | %{$_.parameters}";

                string getManagementCustomRolePipeRoleEntryParams = "Get-ManagementRole \"" + selectedRole + "\" | %{$_.RoleEntries} | ?{$_.name -eq \"" + selectedRoleEntry + "\"} | %{$_.parameters}";

                Collection<PSObject> getManagementCustomRolePipeRoleEntryParamsResults = resultOfCmdlet(getManagementCustomRolePipeRoleEntryParams);
                foreach (PSObject customEntryParams in getManagementCustomRolePipeRoleEntryParamsResults)
                {
                    customRoleEntryParametersList.Add(customEntryParams.ToString());
                }
            }

            
            
            Collection<PSObject> getManagementRolePipeRoleEntryParamsResults = resultOfCmdlet(getManagementRolePipeRoleEntryParams);
            foreach (PSObject entryParam in getManagementRolePipeRoleEntryParamsResults)
            {
                checkedListBoxRoleEntryParams.Items.Add(entryParam.ToString());
                if (selectedMgmtRoleType == "Role")
                    checkedListBoxRoleEntryParams.SetItemCheckState(listBoxIndex, CheckState.Indeterminate);
                else if(customRoleEntryParametersList.Contains(entryParam.ToString()))
                    checkedListBoxRoleEntryParams.SetItemCheckState(listBoxIndex, CheckState.Checked);
                else if(customRoleEntryParametersList.Count == 0)
                    checkedListBoxRoleEntryParams.SetItemCheckState(listBoxIndex, CheckState.Indeterminate);
                else
                    checkedListBoxRoleEntryParams.SetItemCheckState(listBoxIndex, CheckState.Unchecked);


                listBoxIndex++;
            }
            showRoleEntryParametersWorking = false;
        }
        //CREATE NEW MANAGEMENT ROLE
        private void showRoleEntriesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form2 newRoleForm = new Form2();
            newRoleForm.ShowDialog();
            //newRoleForm.Close();
            string newManagementRole = "New-ManagementRole -Name \"" + newRoleForm.customRoleNametextBox.Text + "\" -Parent \"" + selectedRole +"\"";
            Collection<PSObject> newManagementRoleResults = resultOfCmdlet(newManagementRole);

            showRoles("none", "none");
            //treeRoles.Nodes[selectedRoleIndex].Nodes.Add(newRoleForm.customRoleNametextBox.Text);
            //int customRoleCount = treeRoles.Nodes[selectedRoleIndex].Nodes.Count;
            //treeRoles.Nodes[selectedRoleIndex].Nodes[customRoleCount-1].Tag = "Role";
            //treeRoles.Nodes[selectedRoleIndex].Nodes[customRoleCount-1].ForeColor = System.Drawing.Color.Green;
            treeRoles.Nodes[selectedRoleIndex].Expand();
        }

        //PARAMETERS CHECKEDLISTBOX VALUE CHANGE
        private void checkedListBoxRoleEntries_SelectedValueChanged(object sender, EventArgs e)
        {
             selectedRoleEntry = checkedListBoxRoleEntries.SelectedItem.ToString();
             //labelSelectedRoleEntry.Text = selectedRoleEntry;
            
            //checkedListBoxRoleEntries.SetItemChecked(checkedListBoxRoleEntries.SelectedIndex, true);
            
            showRoleEntryParameters();
        } 

        private void checkedListBoxRoleEntries_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            if (selectedMgmtRoleType == "Role" || e.Index == 0)
            {
                if (e.NewValue == CheckState.Unchecked || e.NewValue == CheckState.Checked)
                    e.NewValue = CheckState.Indeterminate;
            }

            else
            {
                if (e.NewValue == CheckState.Unchecked && showRoleEntriesWorking == false)
                {
                    string removeManagementRoleEntry = "Remove-ManagementRoleEntry -Identity " + selectedRole + "\\" + selectedRoleEntry + " -Confirm:$false";
                    Collection<PSObject> removeManagementRoleEntryResults = resultOfCmdlet(removeManagementRoleEntry);

                    //checkedListBoxRoleEntries.SelectedIndex = e.Index;
                    //showRoleEntryParameters();
                }

                if (e.NewValue == CheckState.Checked && showRoleEntriesWorking == false)
                {
                    string addManagementRoleEntry = "Add-ManagementRoleEntry -Identity " + selectedRole + "\\" + selectedRoleEntry + " -Confirm:$false";
                    Collection<PSObject> addManagementRoleEntryResults = resultOfCmdlet(addManagementRoleEntry);

                    //checkedListBoxRoleEntries.SelectedIndex = e.Index;

                    //showRoleEntryParameters();
                }
            }
        }
      
        private void checkedListBoxRoleEntryParams_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            selectedRoleEntryParameter = checkedListBoxRoleEntryParams.Items[e.Index].ToString();
            if (selectedMgmtRoleType == "Role")
            {
                if (e.NewValue == CheckState.Unchecked || e.NewValue == CheckState.Checked)
                    e.NewValue = CheckState.Indeterminate;
            }

            else
            {
                if (e.NewValue == CheckState.Unchecked && showRoleEntryParametersWorking == false)
                {
                    string removeManagementRoleEntryParameter = "Set-ManagementRoleEntry -Identity " + selectedRole + "\\" + selectedRoleEntry + " -Parameters " + selectedRoleEntryParameter + " -RemoveParameter -Confirm:$false";
                    Collection<PSObject> removeManagementRoleEntryParameterResults = resultOfCmdlet(removeManagementRoleEntryParameter);
                }

                if (e.NewValue == CheckState.Checked && showRoleEntryParametersWorking == false)
                {
                    string addManagementRoleEntryParameter = "Set-ManagementRoleEntry -Identity " + selectedRole + "\\" + selectedRoleEntry + " -Parameters " + selectedRoleEntryParameter + " -AddParameter -Confirm:$false";
                    Collection<PSObject> addManagementRoleEntryParameterResults = resultOfCmdlet(addManagementRoleEntryParameter);
                }

            }

        }

        private void removeRoleToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form3 newAssignmentForm = new Form3();
            newAssignmentForm.assignmentNameTextBox.Text = selectedRole;
            newAssignmentForm.ShowDialog();
            
            string newManagementRoleAssignment = "New-ManagementRoleAssignment -Name \"" + newAssignmentForm.assignmentNameTextBox.Text + "\" -Role \"" + selectedRole +"\" -SecurityGroup \"" + newAssignmentForm.groupNameTextBox.Text + "\"";
            Collection<PSObject> newManagementRoleAssignmentResult = resultOfCmdlet(newManagementRoleAssignment);

            showAssingments();
        }

        private void removeRoleToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            string removeManagementRole = "Remove-ManagementRole -Identity \"" + selectedRole + "\" -Confirm:$false";
            Collection<PSObject> removeManagementRoleResults = resultOfCmdlet(removeManagementRole);
            showRoles("none", "none");
        }

        private void treeAssignments_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                Point p = new Point(e.X, e.Y);
                TreeNode node = treeAssignments.GetNodeAt(p);

                if (node != null)
                {
                    //m_OldSelectNode2 = connectorsTree.SelectedNode;
                    treeAssignments.SelectedNode = node;
                    selectedAssignment = treeAssignments.SelectedNode.ToString().Replace("TreeNode:", "").Trim();

                    switch (Convert.ToString(node.Tag))
                    {
                        case "Server?": //RESERVED FOR FUTURE RELEASES
                            //connectorContextMenu.Show (treeReceiveConnector, p);
                            break;
                        case "Assignment":
                            assignmentContextMenu.Show(treeAssignments, p);
                            break;
                        case "CustomRole":
                            customRolesContextMenu.Show(treeRoles, p);
                            break;
                    }
                }
            }
        }

        private void removeAssignmentToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string removeManagementRoleAssignment = "Remove-ManagementRoleAssignment -Identity \"" + selectedAssignment + "\" -Confirm:$false";
            Collection<PSObject> removeManagementRoleAssignmentResults = resultOfCmdlet(removeManagementRoleAssignment);
            showAssingments();
        }

        private void populateCmdletFilters()
        {
            cmdletFiltertextBox.AutoCompleteCustomSource.Add("none");
            string getCommandModule = "Get-Command -Module Microsoft.Exchange.Management.PowerShell.E2010";
            Collection<PSObject> getCommandModuleResults = resultOfCmdlet(getCommandModule);
            foreach (PSObject command in getCommandModuleResults)
            {
                cmdletFiltertextBox.AutoCompleteCustomSource.Add(command.Properties["Name"].Value.ToString());
            }

        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutBox1 ab = new AboutBox1();
            ab.ShowDialog();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        
    }
}
